from Crypto.PublicKey import RSA
from Crypto.Cipher import Blowfish
from Crypto import Random
import random, string

class BlowfishCipher():
    def __init__(self):
        self.KEY_LENGTH = 128
        self.BLOCK_SIZE = 8
        self.key = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(self.KEY_LENGTH))
        self.__cipher = Blowfish.new(self.key, Blowfish.MODE_ECB)        
    def __pad(self, msg):
        pad_bytes = self.BLOCK_SIZE - (len(msg) % self.BLOCK_SIZE)                                 
        for i in range(pad_bytes - 1): msg += chr(random.randrange(0, 256))
        # final padding byte; % by 8 to get the number of padding bytes
        bflag = random.randrange(6, 248); bflag -= bflag % 8 - pad_bytes
        msg += chr(bflag)
        return msg
    def __depad(self, msg):
        pad_bytes = ord(msg[-1]) % self.BLOCK_SIZE
        if not pad_bytes: pad_bytes = self.BLOCK_SIZE
        return msg[:-pad_bytes]        
    def encrypt(self, plain):
        return self.__cipher.encrypt(self.__pad(plain))
    def decrypt(self, encrypted):
        return self.__depad(self.__cipher.decrypt(encrypted))


class RSACipher():
    def __init__(self):
        self.KEY_LENGTH = 1024        
    def generate_keys(self):
        self.__privatekeyCMS = RSA.generate(self.KEY_LENGTH, Random.get_random_bytes)
        self.__privatekey = RSA.generate(self.KEY_LENGTH, Random.get_random_bytes)
        self.publickeyCMS = self.__privatekeyCMS.publickey()
        self.publickey = self.__privatekey.publickey()
    def sign(self, secret):
        return self.__privatekeyCMS.sign(secret, "")
    def encrypt(self, secret):
        enc = self.publickey.encrypt(secret, "")
        return enc[0] 
    def decrypt(self, secret): 
        return self.__privatekey.decrypt(secret)    
    def show_keys(self):
        print self.__privatekey
        print self.publickey 
            

class RSAclient():
    def __init__(self, public_key):
        self.publickey = public_key    
    def encrypt(self, secret):
        enc = self.publickey.encrypt(secret, "")
        return enc[0] 



'''
signed_PWD = privatekeyCMS.sign(PWD,"")
enc_PWD = 
print "with publickeyClient encrypted AES-PWD:"
print enc_PWD
print "with privatekeyCMS signed AES-PWD:"
print signed_PWD


dec_PWD= privatekeyClient.decrypt(enc_PWD[0])
print "identity check:\n",publickeyCMS.verify(dec_PWD,signed_PWD)
print "decrypted PWD:\n",dec_PWD

'''